package Xproer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.zip.DataFormatException;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.PageContext;
import org.apache.commons.fileupload.FileItem;

/**
 * 上传对象
 * 更新记录：
 * 	2013-01-25 创建
 *
 */
public class Uploader {
	
	public PageContext m_pc;
	String m_folder;		//上传文件夹。D:\\webapps\\WordPaster\\upload\\
	String m_curBasePath;	//当前文件路径。http://localhost:8080/WordPaster/
	String m_filePathRel;	//文件在服务器中的相对路径。http://localhost:8080/WordPaster/upload/2012/05/24/
	String m_fileName;		//文件名称。11223344.png
	
	/*
	 * 在JSP页面中构造。传入 pageContext
	 * */
	public Uploader(PageContext pc,HttpServletRequest sr)
	{
		this.m_pc = pc;
		String path = sr.getContextPath();
		this.m_curBasePath = sr.getScheme()+"://" + sr.getServerName()+":" + sr.getServerPort() + path+"/";
	}

	/*
	 * 获取文件相对路径。
	 * 返回值：
	 * 		http://localhost:8080/WordPaster/upload/2012/05/24/11223344.png
	 * */
	public String GetFilePathRel()
	{
		return this.m_filePathRel + this.m_fileName;
	}
	
	/*
	 * 创建上传文件夹
	 * 2012\\05\\24\\
	 * */
	public void CreateFolder()
	{
		Date timeCur = new Date();
		SimpleDateFormat fmtYY = new SimpleDateFormat("yyyy");
		SimpleDateFormat fmtMM = new SimpleDateFormat("MM");
		SimpleDateFormat fmtDD = new SimpleDateFormat("dd");
		String strYY = fmtYY.format(timeCur);
		String strMM = fmtMM.format(timeCur);
		String strDD = fmtDD.format(timeCur);
		
		//相对路径/2012/05/24/
		String pathRel = "upload/" + strYY + "/" + strMM + "/" + strDD + "/";
		String pathAbs = "upload\\" + strYY + "\\" + strMM + "\\" + strDD + "\\";
		//文件路径
		this.m_filePathRel = this.m_curBasePath + pathRel;
		
		this.m_folder = this.m_pc.getServletContext().getRealPath("/") + pathAbs;
		
		File f = new File(this.m_folder);
		//文件夹不存在
		if(!f.exists())
		{
			f.mkdirs();
		}		
	}
	
	/*
	 * 根据当前时间生成文件名称。
	 * 返回值：
	 * 		年月日，时分秒
	 * 		2012-05-24-16-06
	 * */
	public String GenerateFileName()
	{
		Date timeCur = new Date();
		SimpleDateFormat fmt = new SimpleDateFormat("HHmmssSSSS");
		String timeStr = fmt.format(timeCur);
		return timeStr;
	}
	
	//将文件保存到服务器中
	public void SaveFile(FileItem upFile) throws IOException
	{
		String nameSvr = upFile.getName();
		this.m_fileName = nameSvr;
			
		int pos = nameSvr.indexOf('.');
		String ext = nameSvr.substring(pos);
		ext.toLowerCase();		
		
		this.CreateFolder();
		String pathSvr = this.m_folder + nameSvr;		

		InputStream stream = upFile.getInputStream();			
		byte[] data = new byte[(int)upFile.getSize()];//128k
		int readLen = stream.read(data);//实际读取的大小
		stream.close();
		
		RandomAccessFile raf = new RandomAccessFile(pathSvr,"rw");
		//定位文件位置
		raf.write(data);
		raf.close();		
	}
	
	public byte[] decompress(byte[] data) throws IOException,DataFormatException
	{
	   Inflater inflater = new Inflater();   
	   inflater.setInput(data);  
	   
	   ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);  
	   byte[] buffer = new byte[1024];  
	   while (!inflater.finished()) 
	   {  
		   int count = inflater.inflate(buffer);
		   outputStream.write(buffer, 0, count);  
	   }  
	   outputStream.close();  
	   byte[] output = outputStream.toByteArray();  
	     
	   return output;
	}
	
	public byte[] decompress1(byte[] data) throws IOException
	{
		ByteArrayInputStream bais = new ByteArrayInputStream(data);  
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        GZIPInputStream gis = new GZIPInputStream(bais);
        
        int count;  
        byte buffer[] = new byte[1024];
        while ((count = gis.read(buffer, 0, 1024)) != -1) {  
            baos.write(buffer, 0, count);  
        }
        gis.close();
        byte[] output = baos.toByteArray();
        baos.flush();
        baos.close();
        bais.close();
        
        return output;
	}
	
	public void SaveZipFile(FileItem f) throws IOException, DataFormatException
	{
		//11223344.png
		String nameSvr = f.getName();
		this.m_fileName = nameSvr;
			
		int pos = nameSvr.indexOf('.');
		String ext = nameSvr.substring(pos);
		ext.toLowerCase();
		
		this.CreateFolder();
		String pathSvr = this.m_folder + nameSvr;		

		InputStream stream = f.getInputStream();			
		byte[] dataCmp = new byte[(int)f.getSize()];//128k
		int readLen = stream.read(dataCmp);//实际读取的大小
		stream.close();
		//解压
		byte[] dataFile = this.decompress(dataCmp);
		
		RandomAccessFile raf = new RandomAccessFile(pathSvr,"rw");
		//定位文件位置
		raf.write(dataFile);
		raf.close();		
	}
	
	public void SaveGZipFile(FileItem f) throws IOException
	{
		String nameSvr = f.getName();
		this.m_fileName = nameSvr;
			
		int pos = nameSvr.indexOf('.');
		String ext = nameSvr.substring(pos);
		ext.toLowerCase();		
		
		this.CreateFolder();
		String pathSvr = this.m_folder + nameSvr;		

		InputStream stream = f.getInputStream();			
		byte[] dataCmp = new byte[(int)f.getSize()];//128k
		int readLen = stream.read(dataCmp);//实际读取的大小
		stream.close();
		//解压
		byte[] dataFile = this.decompress1(dataCmp);
		
		RandomAccessFile raf = new RandomAccessFile(pathSvr,"rw");
		//定位文件位置
		raf.write(dataFile);
		raf.close();		
	}
	
	public final static byte[] base64Encode(byte[] byteData) {
	    if (byteData == null)
	        return null;
	    int iSrcIdx; // index into source (byteData)
	    int iDestIdx; // index into destination (byteDest)
	    byte byteDest[] = new byte[((byteData.length + 2) / 3) * 4];

	    for (iSrcIdx = 0, iDestIdx = 0; iSrcIdx < byteData.length - 2; iSrcIdx += 3) {
	        byteDest[iDestIdx++] = (byte) ((byteData[iSrcIdx] >>> 2) & 077);
	        byteDest[iDestIdx++] = 
	            (byte) ((byteData[iSrcIdx + 1] >>> 4) & 017 | (byteData[iSrcIdx] << 4) & 077); 
	        byteDest[iDestIdx++] = 
	            (byte) ((byteData[iSrcIdx + 2] >>> 6)
	                & 003
	                | (byteData[iSrcIdx + 1] << 2)
	                & 077); 
	        byteDest[iDestIdx++] = (byte) (byteData[iSrcIdx + 2] & 077);
	    }

	    if (iSrcIdx < byteData.length) {
	        byteDest[iDestIdx++] = (byte) ((byteData[iSrcIdx] >>> 2) & 077);
	        if (iSrcIdx < byteData.length - 1) {
	            byteDest[iDestIdx++] = 
	                (byte) ((byteData[iSrcIdx + 1] >>> 4) & 017 | (byteData[iSrcIdx] << 4) & 077); 
	            byteDest[iDestIdx++] = (byte) ((byteData[iSrcIdx + 1] << 2) & 077);
	        } else
	            byteDest[iDestIdx++] = (byte) ((byteData[iSrcIdx] << 4) & 077);
	    }

	    for (iSrcIdx = 0; iSrcIdx < iDestIdx; iSrcIdx++) {
	        if (byteDest[iSrcIdx] < 26)
	            byteDest[iSrcIdx] = (byte) (byteDest[iSrcIdx] + 'A');
	        else
	            if (byteDest[iSrcIdx] < 52)
	                byteDest[iSrcIdx] = (byte) (byteDest[iSrcIdx] + 'a' - 26);
	            else
	                if (byteDest[iSrcIdx] < 62)
	                    byteDest[iSrcIdx] = (byte) (byteDest[iSrcIdx] + '0' - 52);
	                else
	                    if (byteDest[iSrcIdx] < 63)
	                        byteDest[iSrcIdx] = (byte) '+';
	                    else
	                        byteDest[iSrcIdx] = (byte) '/';
	    }

	    for (; iSrcIdx < byteDest.length; iSrcIdx++)
	        byteDest[iSrcIdx] = (byte) '=';

	    return byteDest;
	}
	
	public final static String base64Encode(String strInput) {
	    if (strInput == null)
	        return null;
	    return base64Encode(strInput,"GB2312");
	}
	
	public final static String base64Encode(String strInput,String charSet) {
	    if (strInput == null)
	        return null;
	    String strOutput=null;
	    byte byteData[] = new byte[strInput.length()];
	    try {
	        //strInput.getBytes(0, strInput.length(), byteData, 0);
	        byteData = strInput.getBytes(charSet);
	        strOutput=new String(base64Encode(byteData),charSet);
	        //strOutput=new String(base64Encode(byteData),0);
	    } catch (UnsupportedEncodingException e) {
	        return null;
	    }
	    return strOutput;
	}
	
	/**
	* 此处插入方法说明。
	* 创建日期：(2000-11-4 18:27:35)
	* @param steam java.io.InputStream
	* @param charSet java.lang.String
	*/
	public final static String base64Encode(InputStream in, String charSet) {
	    try {
	        int c;
	        byte[] buff = new byte[1024];
	        ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
	        while ((c = in.read(buff, 0, 1024)) != -1) {
	            out.write(buff, 0, c);
	            //index+=1024;
	            //out.write(c);
	            //attachContent+=ss;
	        }
	        in.close();
	        out.flush();
	        byte[] tmp2 = base64Encode(out.toByteArray());
	        out.close();
	        return new String(tmp2,charSet);
	    }
	    catch (IOException e) {
	        return "";
	    }
	}
	
	/**
	* 此处插入方法说明。
	* 创建日期：(2000-11-3 23:31:04)
	* @return java.lang.String
	* @param strIn java.lang.String
	*/  
	public final static String chunkSplit(String strIn) {
	    return chunkSplit(strIn,76);
	}
	
	/**
	* 此处插入方法说明。
	* 创建日期：(2000-11-3 23:31:04)
	* @return java.lang.String
	* @param strIn java.lang.String
	*/  
	public final static String chunkSplit(String strIn,int splitLen) {
	    int index=0;
	    String strOut="";
	    while(index+splitLen<strIn.length()){
	        strOut+=strIn.substring(index,index+splitLen)+"\n";
	        index+=splitLen;
	    }
	    if(index<strIn.length()){
	        strOut+=strIn.substring(index);
	    }
	    return strOut;
	}
}